package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.framework.config.properties.WxCpProperties;
import com.ruoyi.system.domain.ProSubject;
import com.ruoyi.system.domain.bo.ProSubjectBo;
import com.ruoyi.system.domain.vo.ProSubjectVo;
import com.ruoyi.system.service.IProSubjectService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.IWxService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.bo.ProTaskBo;
import com.ruoyi.system.domain.vo.ProTaskVo;
import com.ruoyi.system.domain.ProTask;
import com.ruoyi.system.mapper.ProTaskMapper;
import com.ruoyi.system.service.IProTaskService;

import java.util.*;

/**
 * 任务管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-10
 */
@RequiredArgsConstructor
@Service
public class ProTaskServiceImpl implements IProTaskService {

    private final ProTaskMapper baseMapper;

    private final IProSubjectService proSubjectService;

    private final ISysUserService sysUserService;
    private final IWxService wxService;

    private WxCpProperties properties;

    /**
     * 查询任务管理
     */
    @Override
    public ProTaskVo queryById(Long taskId){
        ProTaskVo proTaskVo = baseMapper.selectVoById(taskId);
        proTaskVo.setHeadUsers(this.parseUsersBynames(proTaskVo.getHeadUser()));
        proTaskVo.setCopyUsers(this.parseUsersBynames(proTaskVo.getCopyUser()));
        return proTaskVo;
    }

    /**
     * 查询任务管理列表
     */
    @Override
    public TableDataInfo<ProTaskVo> queryPageList(ProTaskBo bo, PageQuery pageQuery) {
        QueryWrapper<ProTask> lqw = buildQuery(bo);
//        String username = LoginHelper.getUsername();
//        if(!"admin".equals(username)){{
//            lqw.and(lq->{
//                lq.eq(ProTask::getCreateBy, username)
//                    .or()
//                    .like(ProTask::getHeadUser, username+",")
//                    .or()
//                    .like(ProTask::getCopyUser, username+",");
//            });
//        }}

        Page<ProTaskVo> result = baseMapper.selectPageList(pageQuery.build(), lqw);
        result.getRecords().forEach(item->{
            item.setHeadUsers(this.parseUsersBynames(item.getHeadUser()));
            item.setCopyUsers(this.parseUsersBynames(item.getCopyUser()));
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询任务管理列表
     */
    @Override
    public List<ProTaskVo> queryList(ProTaskBo bo) {
        QueryWrapper<ProTask> lqw = buildQuery(bo);
        return baseMapper.selectPageList(lqw);
    }

    private ArrayList<SysUser> parseUsersBynames(String headUser){
        ArrayList<SysUser> headUsers = new ArrayList<>();
        if(StringUtils.isNotBlank(headUser)){
            String[] split = headUser.split(",");
            for (String username : split) {
                SysUser sysUser = sysUserService.selectUserByUserName(username);
                if(ObjectUtils.isNotNull(sysUser)){
                    headUsers.add(sysUser);
                }
            }
        }
        return headUsers;
    }
    private QueryWrapper<ProTask> buildQuery(ProTaskBo bo) {
        String username = LoginHelper.getUsername();
        Map<String, Object> params = bo.getParams();
        QueryWrapper<ProTask> queryWrapper = new QueryWrapper<>();
        if(!"admin".equals(username)) {
            queryWrapper.and(lqw -> {
                lqw.eq("pt.create_by", username).or();
                lqw.like("pt.head_user", username + ",").or();
                lqw.like("pt.copy_user", username + ",").or();
                lqw.eq("ps.create_by", username).or();
                lqw.like("ps.head_user", username + ",").or();
                lqw.like("ps.copy_user", username + ",");
            });
        }
        queryWrapper.like(StringUtils.isNotBlank(bo.getSubjectName()), "pt.task_name", bo.getTaskName());
        queryWrapper.eq(StringUtils.isNotBlank(bo.getCategory()), "pt.category", bo.getCategory());
        queryWrapper.eq(StringUtils.isNotBlank(bo.getStatus()), "pt.status", bo.getStatus());
        queryWrapper.eq(ObjectUtil.isNotNull(bo.getSubjectId()), "pt.subject_id", bo.getSubjectId());
        queryWrapper.orderBy(true,false,"pt.create_time");
        return queryWrapper;
    }

    private LambdaQueryWrapper<ProTask> buildQueryWrapper(ProTaskBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ProTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDdate() != null, ProTask::getDdate, bo.getDdate());
        lqw.like(StringUtils.isNotBlank(bo.getTaskName()), ProTask::getTaskName, bo.getTaskName());
        lqw.eq(StringUtils.isNotBlank(bo.getDesp()), ProTask::getDesp, bo.getDesp());
        lqw.eq(bo.getFireDate() != null, ProTask::getFireDate, bo.getFireDate());
        lqw.eq(bo.getDemandDate() != null, ProTask::getDemandDate, bo.getDemandDate());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ProTask::getStatus, bo.getStatus());
        lqw.eq(ObjectUtil.isNotNull(bo.getSubjectId()), ProTask::getSubjectId, bo.getSubjectId());
        lqw.eq(StringUtils.isNotBlank(bo.getHeadUser()), ProTask::getHeadUser, bo.getHeadUser());
        lqw.eq(StringUtils.isNotBlank(bo.getCopyUser()), ProTask::getCopyUser, bo.getCopyUser());
        return lqw;
    }


    /**
     * 新增任务管理
     */
    @Override
    public Boolean insertByBo(ProTaskBo bo) {
        ProTask add = BeanUtil.toBean(bo, ProTask.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        String msg = generateMsgByProTask(bo);

        if(StringUtils.isNotEmpty(bo.getHeadUser())||StringUtils.isNotEmpty(bo.getCopyUser())){
            wxService.sendMessageByText2Copy(
                bo.getCopyUser().replace(",","|")
                    +bo.getHeadUser().replace(",","|"),
                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+add.getTaskId()),
                bo.getTaskName(),
                msg);
//
//            wxService.sendMessage2Copy(
//                bo.getCopyUser().replace(",","|")
//                    +bo.getHeadUser().replace(",","|"),
//                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+add.getTaskId()),
//                msg);
        }
        ProSubjectVo proSubjectVo = proSubjectService.queryById(bo.getSubjectId());
        if(proSubjectVo.getStatus().equals(STATUS_NEW)){
            proSubjectVo.setStatus(STATUS_PROCESS);
            ProSubjectBo proSubjectBo = BeanUtil.toBean(proSubjectVo, ProSubjectBo.class);
            proSubjectService.updateByBo(proSubjectBo);
        }
        wxService.sendMessageByText2Copy(
            proSubjectVo.getCopyUser().replace(",","|")
                +proSubjectVo.getHeadUser().replace(",","|"),
            this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+add.getTaskId()),
            bo.getTaskName(),
            msg);
        if (flag) {
            bo.setTaskId(add.getTaskId());
        }
        return flag;
    }

    private String generateMsgByProTask(ProTaskBo bo){
        String msg = "任务"+bo.getTaskName();
        msg += ",描述： "+bo.getDesp();
        return msg;
    }

    /**
     * 修改任务管理
     */
    @Override
    public Boolean updateByBo(ProTaskBo bo) {
        if(!canEdit(bo)){
            throw new ServiceException("你没有编辑权限");
        }
        ProTask update = BeanUtil.toBean(bo, ProTask.class);
        if("新建".equals(update.getStatus())&&update.getRate() > 0){
            update.setStatus("执行中");
        }
        validEntityBeforeSave(update);
        ProSubjectVo proSubjectVo = proSubjectService.queryById(bo.getSubjectId());
        ProTask proTask = baseMapper.selectById(update.getTaskId());
        if(update.getRate() != proTask.getRate()){
            String msg = generateMsgByProTask(bo);
            if(StringUtils.isNotEmpty(bo.getCopyUser())||StringUtils.isNotEmpty(bo.getHeadUser())){
                wxService.sendMessageByText2Copy(
                    this.parseUserByTask(bo,false),
                    this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+proTask.getTaskId()),
                    bo.getTaskName(),
                    msg);
//
//            wxService.sendMessage2Copy(
//                bo.getCopyUser().replace(",","|")
//                    +bo.getHeadUser().replace(",","|"),
//                this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+proTask.getTaskId()),
//                msg);
            }
            if(update.getRate() == 100){
                update.setStatus("已完成");
                wxService.sendMessageByText2Copy(
                    this.parseUserByTask(bo,true),
                    this.generateUrl("http://emswx.kennede.com:49865/prod-api/unauth/toDetail?id="+update.getTaskId()),
                    bo.getTaskName(),
                    msg);
            }

        }
        proTask.setStatus(update.getStatus());
        proTask.setTaskName(update.getTaskName());
        proTask.setDesp(update.getDesp());
        proTask.setRate(update.getRate());
        proTask.setCopyUser(update.getCopyUser());
        proTask.setHeadUser(update.getHeadUser());
        proTask.setFireDate(update.getFireDate());
        proTask.setDemandDate(update.getDemandDate());
        return baseMapper.updateById(proTask) > 0;
    }
    private String generateUrl(String uri){
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"+
        "appid=wwe7858c0d51254286"+
            "&redirect_uri="+uri+
            "&response_type=code&scope=snsapi_userinfo&state=STATE"+
            "&agentid=1000013#wechat_redirect";
        return url;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ProTask entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除任务管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    private boolean canEdit(ProTaskBo bo){
        String username = LoginHelper.getLoginUser().getUsername();
        if("admin".equals(username)){
            return true;
        }
        ProTask proTask = baseMapper.selectById(bo.getTaskId());
        return proTask.getCreateBy().equals(username)||
            proTask.getHeadUser().contains(username);
    }

    private String parseUserByTask(ProTaskBo bo,boolean callSubject){
        String users = "";
        Set<String> userSet = new HashSet<>();
        userSet.addAll(this.parseUser2Set(bo.getHeadUser()));
        userSet.addAll(this.parseUser2Set(bo.getCopyUser()));
        if(callSubject){
            ProSubjectVo proSubjectVo = proSubjectService.queryById(bo.getSubjectId());
            userSet.addAll(this.parseUser2Set(proSubjectVo.getHeadUser()));
            userSet.addAll(this.parseUser2Set(proSubjectVo.getCopyUser()));
        }
        Iterator<String> iterator = userSet.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            if(StringUtils.isNotBlank(next)){
                users +=  next + "|";
            }
        }
        return users;
    }
    private Set<String> parseUser2Set(String users){
        Set<String> userSet = new HashSet<>();
        if(StringUtils.isNotBlank(users)){
            String[] split = users.split(",");
            for (String s : split) {
                userSet.add(s);
            }
        }
        return userSet;
    }

}
